package com.lp.common.handler;

import com.lp.common.exception.BaseException;
import com.lp.common.utils.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import static com.lp.common.exception.ErrorCodeEnum.*;

/**
 * @program: backend
 * @description:
 * @author: Ke.Song
 * @since: 2024-03-11 21:16:25
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @Autowired
    private Environment env;

    private final String PROD = "prod";

    /**
     * Handle base exception response entity.
     *
     * @param exception the exception
     * @return the response entity
     */
    @ResponseBody
    @ExceptionHandler(BaseException.class)
    public CommonResult handleBaseException(BaseException exception){
        log.error(exception.getMessage());
        return CommonResult.error(exception.getBizCode(),exception.getMessage(env.matchesProfiles(PROD)));
    }

    /**
     * Handle base exception response entity.
     *
     * @param exception the exception
     * @return the response entity
     */
    @ResponseBody
    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    public CommonResult handleBaseException(MethodArgumentTypeMismatchException exception){
        log.error(exception.getCause().getMessage());
        return CommonResult.error(PARAMS_ERROR.getBizCode(), PARAMS_ERROR.getMsg());
    }

    /**
     * 运行异常处理
     *
     * @param error 异常对象
     * @return 响应对象 response entity
     */
    @ExceptionHandler(RuntimeException.class)
    public CommonResult handleException(RuntimeException error) {
        log.error("RuntimeException message -> {}", error.getMessage());
        return CommonResult.error(SERVER_ERROR.getBizCode(), SERVER_ERROR.getMsg());
    }

    /**
     * 其他系统异常处理
     *
     * @param error 异常对象
     * @return 响应对象 response entity
     */
    @ExceptionHandler(Exception.class)
    public CommonResult handleException(Exception error) {
        log.error("Exception message -> {}", error.getMessage());
        return CommonResult.error(SERVER_ERROR.getBizCode(), SERVER_ERROR.getMsg());
    }

    /**
     * 请求类型校验
     *
     * @param e the e
     * @return the response entity
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public CommonResult handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        log.error(e.getMessage());
        return CommonResult.error(FAILED.getBizCode(), FAILED.getMsg());
    }

    /**
     * 方法参数校验
     *
     * @param e the e
     * @return the response entity
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public CommonResult httpMessageNotReadableException(HttpMessageNotReadableException e) {
        log.error(e.getMessage());
        return CommonResult.error(PARAMS_ERROR.getBizCode(), checkMsg(e.getMessage()));
    }

    /**
     * 方法参数校验
     *
     * @param e the e
     * @return the response entity
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public CommonResult httpMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
        return CommonResult.error(PARAMS_ERROR.getBizCode(),
                checkMsg(e.getBindingResult().getAllErrors().get(0).getDefaultMessage()));
    }

    /**
     * 方法参数校验
     *
     * @param e the e
     * @return the response entity
     */
    @ExceptionHandler(BindException.class)
    public CommonResult httpMethodArgumentNotValidException(BindException e) {
        log.error(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
        return CommonResult.error(PARAMS_ERROR.getBizCode(),
                checkMsg(e.getBindingResult().getAllErrors().get(0).getDefaultMessage()));
    }

    /**
     * 方法参数校验
     *
     * @param e the e
     * @return the response entity
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public CommonResult httpMethodArgumentNotValidException(MissingServletRequestParameterException e) {
        log.error(e.getMessage());
        return CommonResult.error(PARAMS_ERROR.getBizCode(), checkMsg(e.getMessage()));
    }

    private String checkMsg(String msg) {
        if (env.matchesProfiles(PROD)) {
            msg = PARAMS_ERROR.getMsg();
        }
        return msg;
    }

}

